package procsim;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class OpenDialog extends JDialog implements ActionListener, KeyListener {
    private JPanel panel = new JPanel(new BorderLayout());
    private JPanel panelSouth = new JPanel(new FlowLayout());
    private JTextArea ta = new JTextArea();
    private JScrollPane scroll = new JScrollPane(ta, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    private JButton buttonLoad = new JButton("Load");
    private JButton buttonClear = new JButton("Clear");
    private JButton buttonCancel = new JButton("Cancel");
    private Program parent;
    private String text = "", oldtext = "";
    private Memory memory;
    OpenDialog(Memory mem, Program prog){
        setTitle("Opened program");
        parent=prog;
        memory=mem;
        ta.setEditable(false);
        ta.setEnabled(false);
        ta.setDisabledTextColor(Color.BLACK);
        ta.setMargin(new Insets(3, 3, 3, 3));
        panelSouth.add(buttonLoad);
        buttonLoad.addActionListener(this);
        buttonLoad.addKeyListener(this);
        panelSouth.add(buttonClear);
        buttonClear.addActionListener(this);
        buttonClear.addKeyListener(this);
        panelSouth.add(buttonCancel);
        buttonCancel.addActionListener(this);
        buttonCancel.addKeyListener(this);
        panel.add(scroll, "Center");
        panel.add(panelSouth, "South");
        setContentPane(panel);
        setSize(400, 250);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(HIDE_ON_CLOSE);
    }
    public void setText(String str, String title){
        ta.setText(text=str);
        if(text.trim().equals(oldtext.trim()))
            buttonLoad.setEnabled(false);
        else buttonLoad.setEnabled(true);
        if (title!=null)
            setTitle(title);
    }
    private void load(){ // asembliranje koda i obrada gresaka
        int addr = 0x100; // adresa pocetka programa
        String[] lines = text.split("\n");
        if (lines.length==1 && lines[0].equals("")){
            JOptionPane.showMessageDialog(null, "No code found in the provided file.", "Fatal error", JOptionPane.ERROR_MESSAGE);
            setText("", null);
        } else {
            try{
                Assemble.preprocess(lines, addr); // pretprocesiranje celog koda
                for(int i=0; i<lines.length; i++){
                    MSignal[] data = Assemble.assemble(lines[i]); // asembliranje linije
                    if (data!=null)
                        for(int j=0; j<data.length; j++)
                            memory.write(addr++, data[j]); // ucitavanje u memoriju
                }
                parent.setStatus("Program loaded.");
            } catch(AssemblingException e){
                JOptionPane.showMessageDialog(null, e.getMessage(), "Assembling error", JOptionPane.ERROR_MESSAGE);
                parent.setStatus("Assembling error.");
            }
        }
        setVisible(false);
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getActionCommand().equals("Load")){
            load();
            oldtext=text;
            buttonLoad.setEnabled(false);
            setTitle("Loaded program");
            parent.setShowProgram(true);
        }
        else if(e.getActionCommand().equals("Clear")){
            setText(oldtext=text="", null);
            buttonLoad.setEnabled(true);
            setVisible(false);
            parent.setShowProgram(false);
        }
        else if(e.getActionCommand().equals("Cancel")){
            setText(text=oldtext, null);
            setVisible(false);
        }
    }
    @Override
    public void keyTyped(KeyEvent ke) { }
    @Override
    public void keyPressed(KeyEvent ke) {
        if(ke.getKeyCode()==KeyEvent.VK_ESCAPE)
            setVisible(false);
        else if(ke.getKeyCode()==KeyEvent.VK_ENTER)
            actionPerformed(new ActionEvent(ke.getComponent(), ActionEvent.ACTION_PERFORMED, ((JButton)ke.getComponent()).getText()));
    }
    @Override
    public void keyReleased(KeyEvent ke) { }
}
